home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / misc / o-z / x-windows / mesa-amiwin / src / pb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-30  |  11.9 KB  |  446 lines

  1. /* pb.c */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995  Brian Paul  (brianp@ssec.wisc.edu)
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25. $Id: pb.c,v 1.25 1995/11/09 16:57:05 brianp Exp $
  26.  
  27. $Log: pb.c,v $
  28.  * Revision 1.25  1995/11/09  16:57:05  brianp
  29.  * added some missing PB.count=0 statements per Johan Nouvel
  30.  *
  31.  * Revision 1.24  1995/11/03  22:36:04  brianp
  32.  * fixed fogging bug
  33.  *
  34.  * Revision 1.23  1995/10/30  15:31:14  brianp
  35.  * added mask argument to gl_mask_[color|index]_pixels calls
  36.  *
  37.  * Revision 1.22  1995/10/19  15:47:51  brianp
  38.  * added gamma support
  39.  *
  40.  * Revision 1.21  1995/10/13  22:41:43  brianp
  41.  * removed dithering code, added color/index masking code
  42.  *
  43.  * Revision 1.20  1995/09/27  19:22:22  brianp
  44.  * optimized several loops, replaced some with memset()
  45.  *
  46.  * Revision 1.19  1995/07/26  15:03:48  brianp
  47.  * replaced some literals with variables for SunOS 4.x per Asif Khan
  48.  *
  49.  * Revision 1.18  1995/07/15  14:04:19  brianp
  50.  * enabled texture mapping
  51.  *
  52.  * Revision 1.17  1995/06/20  16:18:53  brianp
  53.  * removed clipflag logic, clip all pixels
  54.  *
  55.  * Revision 1.16  1995/06/12  15:42:14  brianp
  56.  * changed some indentations
  57.  *
  58.  * Revision 1.15  1995/06/05  20:26:51  brianp
  59.  * better PB.clipflag setup
  60.  *
  61.  * Revision 1.14  1995/05/22  21:02:41  brianp
  62.  * Release 1.2
  63.  *
  64.  * Revision 1.13  1995/05/18  14:43:31  brianp
  65.  * implemented glIndexMask(0) and glColorMask(0,0,0,0)
  66.  *
  67.  * Revision 1.12  1995/05/17  13:17:22  brianp
  68.  * changed default CC.Mode value to allow use of real OpenGL headers
  69.  * removed need for CC.MajorMode variable
  70.  *
  71.  * Revision 1.11  1995/05/12  16:26:33  brianp
  72.  * added pixel clipping
  73.  *
  74.  * Revision 1.10  1995/04/11  14:04:40  brianp
  75.  * changed (*CC.write...) to (*DD.write...)
  76.  *
  77.  * Revision 1.9  1995/03/30  21:07:32  brianp
  78.  * updated to use pointers to CC.write_* functions
  79.  *
  80.  * Revision 1.8  1995/03/27  20:32:17  brianp
  81.  * new Texture.Enabled scheme
  82.  *
  83.  * Revision 1.7  1995/03/08  15:10:02  brianp
  84.  * support for dd_logicop
  85.  *
  86.  * Revision 1.6  1995/03/07  19:02:08  brianp
  87.  * added logicop, blending, and alpha test
  88.  *
  89.  * Revision 1.5  1995/03/07  14:21:05  brianp
  90.  * updated for new XSetForeground/GC scheme
  91.  *
  92.  * Revision 1.4  1995/03/04  19:29:44  brianp
  93.  * 1.1 beta revision
  94.  *
  95.  * Revision 1.3  1995/03/01  17:44:22  brianp
  96.  * added stenciling for PB
  97.  *
  98.  * Revision 1.2  1995/02/27  22:48:56  brianp
  99.  * modified for PB
  100.  *
  101.  * Revision 1.1  1995/02/24  17:51:55  brianp
  102.  * Initial revision
  103.  *
  104.  */
  105.  
  106.  
  107. /*
  108.  * Pixel buffer:
  109.  *
  110.  * As fragments are produced (by point, line, and bitmap drawing) they
  111.  * are accumlated in a buffer.  When the buffer is full or has to be
  112.  * flushed (glEnd), we apply all enabled rasterization functions to the
  113.  * pixels and write the results to the display buffer.  The goal is to
  114.  * maximize the number of pixels processed inside loops and to minimize
  115.  * the number of function calls.
  116.  */
  117.  
  118.  
  119.  
  120. #include <string.h>
  121. #include "alpha.h"
  122. #include "blend.h"
  123. #include "context.h"
  124. #include "dd.h"
  125. #include "depth.h"
  126. #include "fog.h"
  127. #include "gamma.h"
  128. #include "logic.h"
  129. #include "macros.h"
  130. #include "masking.h"
  131. #include "pb.h"
  132. #include "scissor.h"
  133. #include "stencil.h"
  134. #include "texture.h"
  135.  
  136.  
  137. struct pixel_buffer PB;
  138.  
  139.  
  140.  
  141.  
  142. /*
  143.  * Apply the polygon stipple to an array of pixels.
  144.  */
  145. static void stipple_polygon_pixels( GLuint n, const GLint x[], const GLint y[],
  146.                     GLubyte mask[] )
  147. {
  148.    register GLuint i, m, stipple, highbit=0x80000000;
  149.  
  150.    for (i=0;i<n;i++) {
  151.       stipple = CC.PolygonStipple[y[i] % 32];
  152.       m = highbit >> (GLuint) (x[i] % 32);
  153.       if ((m & stipple)==0) {
  154.      mask[i] = 0;
  155.       }
  156.    }
  157. }
  158.  
  159.  
  160.  
  161.  
  162.  
  163. /*
  164.  * Call this to initialize the pixel buffer.  Probably only call in glBegin.
  165.  * Input:  primitive - either GL_POINT, GL_LINE, GL_POLYGON or GL_BITMAP.
  166.  */
  167. void gl_init_pb( GLenum primitive )
  168. {
  169.    PB.count = 0;
  170.    PB.mutable = CC.Texture.Enabled
  171.           || CC.Fog.Enabled
  172.           || CC.Color.BlendEnabled
  173.               || CC.Color.SWLogicOpEnabled
  174.               || CC.Color.SWmasking;
  175.    PB.mono = GL_FALSE;
  176.    PB.primitive = primitive;
  177. }
  178.  
  179.  
  180.  
  181.  
  182. /*
  183.  * When the pixel buffer is full, or needs to be flushed, call this
  184.  * function.  All the pixels in the pixel buffer will be subjected
  185.  * to texturing, scissoring, stippling, alpha testing, stenciling,
  186.  * depth testing, blending, and finally written to the frame buffer.
  187.  */
  188. void gl_flush_pb( void )
  189. {
  190.    GLubyte mask[PB_SIZE+4];   /* add 4 for manually unrolled loop, below */
  191.  
  192. #ifdef DEBUG
  193.    printf("Flush: %d\n", PB.count );
  194. #endif
  195.  
  196.    if (PB.count==0)  return;
  197.  
  198.    /* initialize mask array and clip pixels simultaneously */
  199.    {
  200.       GLint w = CC.BufferWidth;
  201.       GLint h = CC.BufferHeight;
  202.       GLuint i = 0;
  203.       /* manually unrolled loop, OK to go past PB.count */
  204.       do {
  205.          mask[i] = (PB.x[i]>=0) & (PB.x[i]<w) & (PB.y[i]>=0) & (PB.y[i]<h);
  206.          i++;
  207.          mask[i] = (PB.x[i]>=0) & (PB.x[i]<w) & (PB.y[i]>=0) & (PB.y[i]<h);
  208.          i++;
  209.          mask[i] = (PB.x[i]>=0) & (PB.x[i]<w) & (PB.y[i]>=0) & (PB.y[i]<h);
  210.          i++;
  211.          mask[i] = (PB.x[i]>=0) & (PB.x[i]<w) & (PB.y[i]>=0) & (PB.y[i]<h);
  212.          i++;
  213.       } while (i<PB.count);
  214.    }
  215.  
  216.    if (CC.RGBAflag) {
  217.       /* RGBA COLOR PIXELS */
  218.  
  219.       if (PB.mono && PB.mutable) {
  220.      /* Copy flat color to all pixels */
  221.      GLint r, g, b, a;
  222.      r = (GLint) (PB.color[0] * CC.RedScale);
  223.      g = (GLint) (PB.color[1] * CC.GreenScale);
  224.      b = (GLint) (PB.color[2] * CC.BlueScale);
  225.      a = (GLint) (PB.color[3] * CC.AlphaScale);
  226.          MEMSET( PB.r, r, PB.count );
  227.          MEMSET( PB.g, g, PB.count );
  228.          MEMSET( PB.b, b, PB.count );
  229.          MEMSET( PB.a, a, PB.count );
  230.       }
  231.  
  232.       /* If each pixel can be of a different color... */
  233.       if (PB.mutable || !PB.mono) {
  234.  
  235.      if (CC.Texture.Enabled & 2) {
  236.         gl_texture_pixels_2d(PB.count, PB.s, PB.t, PB.r, PB.g, PB.b, PB.a);
  237.      }
  238.      else if (CC.Texture.Enabled & 1) {
  239.         gl_texture_pixels_1d( PB.count, PB.s, PB.r, PB.g, PB.b, PB.a );
  240.      }
  241.  
  242.      if (CC.Fog.Enabled
  243.              && (CC.Hint.Fog==GL_NICEST || PB.primitive==GL_BITMAP)) {
  244.         gl_fog_color_pixels( PB.count, PB.z,
  245.                  PB.r, PB.g, PB.b, PB.a );
  246.      }
  247.  
  248.      if (CC.Scissor.Enabled) {
  249.         if (gl_scissor_pixels( PB.count, PB.x, PB.y, mask )==0) {
  250.            PB.count = 0;
  251.            return;
  252.         }
  253.      }
  254.  
  255.      if (CC.Polygon.StippleFlag && PB.primitive==GL_POLYGON) {
  256.         stipple_polygon_pixels( PB.count, PB.x, PB.y, mask );
  257.      }
  258.  
  259.      if (CC.Color.AlphaEnabled) {
  260.         if (gl_alpha_test( PB.count, PB.a, mask )==0) {
  261.            PB.count = 0;
  262.            return;
  263.         }
  264.      }
  265.  
  266.      if (CC.Stencil.Enabled) {
  267.         /* first stencil test */
  268.         if (gl_stencil_pixels( PB.count, PB.x, PB.y, mask )==0) {
  269.            PB.count = 0;
  270.            return;
  271.         }
  272.         /* depth buffering w/ stencil */
  273.         gl_depth_stencil_pixels( PB.count, PB.x, PB.y, PB.z, mask );
  274.      }
  275.      else if (CC.Depth.Test) {
  276.         /* regular depth testing */
  277.         gl_depth_test_pixels( PB.count, PB.x, PB.y, PB.z, mask );
  278.      }
  279.  
  280.      if (CC.Color.ColorMask) {
  281.             if (CC.Color.SWmasking) {
  282.                gl_mask_color_pixels( PB.count, PB.x, PB.y,
  283.                                      PB.r, PB.g, PB.b, PB.a, mask );
  284.             }
  285.  
  286.             if (CC.Color.BlendEnabled) {
  287.                gl_blend_pixels( PB.count, PB.x, PB.y,
  288.                                 PB.r, PB.g, PB.b, PB.a, mask);
  289.             }
  290.  
  291.             /* write pixels */
  292.             (*DD.write_color_pixels)( PB.count, PB.x, PB.y,
  293.                                       PB.r, PB.g, PB.b, PB.a, mask );
  294.          }
  295.  
  296.       }
  297.       else {
  298.      /* Same color for all pixels */
  299.  
  300.      if (CC.Scissor.Enabled) {
  301.         if (gl_scissor_pixels( PB.count, PB.x, PB.y, mask )==0) {
  302.                PB.count = 0;
  303.            return;
  304.         }
  305.      }
  306.  
  307.      if (CC.Polygon.StippleFlag && PB.primitive==GL_POLYGON) {
  308.         stipple_polygon_pixels( PB.count, PB.x, PB.y, mask );
  309.      }
  310.  
  311.      if (CC.Color.AlphaEnabled) {
  312.         if (gl_alpha_test( PB.count, PB.a, mask )==0) {
  313.                PB.count = 0;
  314.            return;
  315.         }
  316.      }
  317.  
  318.      if (CC.Stencil.Enabled) {
  319.         /* first stencil test */
  320.         if (gl_stencil_pixels( PB.count, PB.x, PB.y, mask )==0) {
  321.                PB.count = 0;
  322.            return;
  323.         }
  324.         /* depth buffering w/ stencil */
  325.         gl_depth_stencil_pixels( PB.count, PB.x, PB.y, PB.z, mask );
  326.      }
  327.      else if (CC.Depth.Test) {
  328.         /* regular depth testing */
  329.         gl_depth_test_pixels( PB.count, PB.x, PB.y, PB.z, mask );
  330.      }
  331.  
  332.      if (CC.Color.ColorMask) {
  333.         /* write pixels */
  334.             GLubyte red, green, blue, alpha;
  335.             red   = (GLint) (PB.color[0] * CC.RedScale);
  336.             green = (GLint) (PB.color[1] * CC.GreenScale);
  337.             blue  = (GLint) (PB.color[2] * CC.BlueScale);
  338.             alpha = (GLint) (PB.color[3] * CC.AlphaScale);
  339.             if (CC.RasterMask & GAMMA_BIT) {
  340.                gl_apply_gamma( 1, &red, &green, &blue );
  341.             }
  342.         (*DD.color)( red, green, blue, alpha );
  343.         (*DD.write_monocolor_pixels)( PB.count, PB.x, PB.y, mask );
  344.      }
  345.       }
  346.    }
  347.    else {
  348.       /* COLOR INDEX PIXELS */
  349.  
  350.       /* If we may be writting pixels with different indexes... */
  351.       if (PB.mono && PB.mutable) {
  352.      /* copy index to all pixels */
  353.          GLuint n = PB.count, indx = PB.index;
  354.          GLuint *pbindex = PB.i;
  355.          do {
  356.         *pbindex++ = indx;
  357.             n--;
  358.      } while (n);
  359.       }
  360.  
  361.       if (PB.mutable || !PB.mono) {
  362.      /* Pixel color index may be modified */
  363.  
  364.      if (CC.Fog.Enabled
  365.              && (CC.Hint.Fog==GL_NICEST || PB.primitive==GL_BITMAP)) {
  366.         gl_fog_index_pixels( PB.count, PB.z, PB.i );
  367.      }
  368.  
  369.      if (CC.Scissor.Enabled) {
  370.         if (gl_scissor_pixels( PB.count, PB.x, PB.y, mask )==0) {
  371.                PB.count = 0;
  372.            return;
  373.         }
  374.      }
  375.  
  376.      if (CC.Polygon.StippleFlag && PB.primitive==GL_POLYGON) {
  377.         stipple_polygon_pixels( PB.count, PB.x, PB.y, mask );
  378.      }
  379.  
  380.      if (CC.Stencil.Enabled) {
  381.         /* first stencil test */
  382.         if (gl_stencil_pixels( PB.count, PB.x, PB.y, mask )==0) {
  383.                PB.count = 0;
  384.            return;
  385.         }
  386.         /* depth buffering w/ stencil */
  387.         gl_depth_stencil_pixels( PB.count, PB.x, PB.y, PB.z, mask );
  388.      }
  389.      else if (CC.Depth.Test) {
  390.         /* regular depth testing */
  391.         gl_depth_test_pixels( PB.count, PB.x, PB.y, PB.z, mask );
  392.      }
  393.  
  394.      if (CC.Color.IndexMask) {
  395.         if (CC.Color.SWLogicOpEnabled) {
  396.            gl_logic_pixels( PB.count, PB.x, PB.y, PB.i, mask );
  397.         }
  398.  
  399.             if (CC.Color.SWmasking) {
  400.                gl_mask_index_pixels( PB.count, PB.x, PB.y, PB.i, mask );
  401.             }
  402.  
  403.         /* write pixels */
  404.         (*DD.write_index_pixels)( PB.count, PB.x, PB.y, PB.i, mask );
  405.      }
  406.       }
  407.       else {
  408.      /* Same color index for all pixels */
  409.  
  410.      if (CC.Scissor.Enabled) {
  411.         if (gl_scissor_pixels( PB.count, PB.x, PB.y, mask )==0) {
  412.                PB.count = 0;
  413.            return;
  414.         }
  415.      }
  416.  
  417.      if (CC.Polygon.StippleFlag && PB.primitive==GL_POLYGON) {
  418.         stipple_polygon_pixels( PB.count, PB.x, PB.y, mask );
  419.      }
  420.  
  421.      if (CC.Stencil.Enabled) {
  422.         /* first stencil test */
  423.         if (gl_stencil_pixels( PB.count, PB.x, PB.y, mask )==0) {
  424.                PB.count = 0;
  425.            return;
  426.         }
  427.         /* depth buffering w/ stencil */
  428.         gl_depth_stencil_pixels( PB.count, PB.x, PB.y, PB.z, mask );
  429.      }
  430.      else if (CC.Depth.Test) {
  431.         /* regular depth testing */
  432.         gl_depth_test_pixels( PB.count, PB.x, PB.y, PB.z, mask );
  433.      }
  434.  
  435.      if (CC.Color.IndexMask) {
  436.         /* write pixels */
  437.         (*DD.index)( PB.index );
  438.         (*DD.write_monoindex_pixels)( PB.count, PB.x, PB.y, mask );
  439.      }
  440.       }
  441.    }
  442.  
  443.    PB.count = 0;
  444. }
  445.  
  446.